package com.xxx.auth.common.interceptor;

import jakarta.servlet.ReadListener;
import jakarta.servlet.ServletInputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequestWrapper;
import lombok.Getter;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;

/**
 * 报错：java.lang.IllegalStateException: getReader() has already been called for this request
 * 原因：request body是流的形式读取，所以getInputStream()和getReader()都只能读取一次
 * 解决：重写方法，使流从保存的body中读取
 */
@Getter
public class RequestWrapper extends HttpServletRequestWrapper {

    private final String body;

    public RequestWrapper(HttpServletRequest request) throws IOException {
        super(request);

        StringBuilder sb = new StringBuilder();
        String line;
        try (BufferedReader reader = request.getReader()) {
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        }
        body = sb.toString();
    }

    @Override
    public BufferedReader getReader() {
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }

    @Override
    public ServletInputStream getInputStream() {
        final byte[] bytes = body.getBytes(StandardCharsets.UTF_8);
        return new ServletInputStream() {
            private int index = 0;

            @Override
            public boolean isFinished() {
                return index >= bytes.length;
            }

            @Override
            public boolean isReady() {
                return true;
            }

            @Override
            public void setReadListener(ReadListener readListener) {
            }

            @Override
            public int read() {
                return index < bytes.length ? bytes[index++] & 0xff : -1;
            }
        };
    }

}
